/*
   This program reads the security descriptor stored in the DefaultAccessPermission
   value of the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole key in the registry
   and then displays the security principals enumerated in the DACL

   This program only works on Windows 2000 and Windows NT
*/

#include <windows.h>
#include <iostream.h>

void main()
{
	cout << "The DefaultAccessPermission value in the " << endl;
	cout << "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Ole " << endl;
	cout << "registry key contains the following information:" << endl;

	// Open the registry key
	HKEY hKeyOLE = NULL;
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Ole", 0, KEY_READ, &hKeyOLE);

	// Read the length of the security descriptor
	DWORD dwSDSize = 0;
	RegQueryValueEx(hKeyOLE, "DefaultAccessPermission", NULL, NULL, NULL, &dwSDSize);

	// Read the security descriptor data
	SECURITY_DESCRIPTOR* pSD = (SECURITY_DESCRIPTOR*)CoTaskMemAlloc(dwSDSize);
	RegQueryValueEx(hKeyOLE, "DefaultAccessPermission", NULL, NULL, (LPBYTE)pSD, &dwSDSize);
	RegCloseKey(hKeyOLE);

	// Get the DACL
	BOOL bHasDacl, bDefaulted;
	ACL* pDACL = NULL;
	GetSecurityDescriptorDacl(pSD, &bHasDacl, &pDACL, &bDefaulted);

	if(pDACL)
	{
		ACE_HEADER* pAce = NULL;
		for(int i = 0; i < pDACL->AceCount; i++)
		{
			// Retrieve the next ACE
			GetAce(pDACL, i, (void**)&pAce);

			// Find the account name given the SID in the ACE
			TCHAR szUser[_MAX_PATH];
			TCHAR szDomain[_MAX_PATH];
			DWORD dwUserSize = sizeof(szUser);
			DWORD dwDomainSize = sizeof(szDomain);
			SID_NAME_USE use;

			LookupAccountSid(NULL, &(((ACCESS_ALLOWED_ACE*)pAce)->SidStart),
				szUser, &dwUserSize, szDomain, &dwDomainSize, &use);

			// Print the principal information
			if(pAce->AceType == ACCESS_ALLOWED_ACE_TYPE)
				cout << "Allow";
			else
				cout << "Deny";
					
			cout << " access to principal " << szDomain << "\\" << szUser << endl;
		}
	}

	// Free the security descriptor
	CoTaskMemFree(pSD);
}